'use strict'
const _ = require('lodash')
const moment = require('moment')

const Controller = require('egg').Controller

class BaseController extends Controller {
  get _ () {
    return _
  }
  get moment () {
    moment.locale('zh-cn')
    return moment
  }
  get modelName () {
    return 'xxxModelName'
  }
  pickPost (paths, ctx = this.ctx) {
    return _.pick(ctx.request.body, paths)
  }
  async getQuery (ctx) {
    // console.log('ctx.query)===========', ctx.query)
    let query = {}
    query = this._.omit(ctx.query, ['limit', 'page', 'sort', 'sortBy', 'order'])
    query = this._.mapValues(query, value => {
      return { $regex: '.*' + value + '.*' }
    })

    return query
  }
  async getSort (ctx) {
    // TODO: sort caculation
    return { createdAt: -1 }
  }
  async list (ctx) {
    console.log('ctx.state)===========', ctx.state)
    let { limit, skip } = ctx.state
    let query = await this.getQuery(ctx)
    let total = await ctx.model[this.modelName].countDocuments(query)
    let items = await ctx.model[this.modelName]
      .find(query)
      .skip(skip)
      .limit(limit)
      .sort(await this.getSort(ctx))
      .lean() // important!!! or map on rz.items will not work
    let rz = {
      total,
      items
    }
    ctx.body = rz
    return rz
  }
  async create (ctx) {
    let data = ctx.request.body
    data['userId'] = _.get(ctx, 'state.user.id')
    console.log('ctx.state.user', ctx.state.user)
    
    let rz = await ctx.model[this.modelName].create(data)
    ctx.body = rz
    return rz
  }
  async read (ctx) {
    let { _id } = ctx.params
    let rz = await ctx.model[this.modelName].findById(_id).lean()
    ctx.body = rz
    return rz
  }
  async update (ctx) {
    let { _id } = ctx.params
    let data = ctx.request.body
    let rz = await ctx.model[this.modelName].findOneAndUpdate(
      { _id },
      { $set: data }
    )
    ctx.body = rz
    return rz
  }
  async delete (ctx) {
    let { _id } = ctx.params
    let rz = await ctx.model[this.modelName].remove({ _id })
    ctx.body = rz
    return rz
  }
  error (code, msg = 'not found') {
    this.ctx.throw(code, msg)
  }
}

module.exports = BaseController
